package hu.rsc.forbiddenwords.client.gui.application;

import hu.rsc.forbiddenwords.client.ForbiddenWordsServiceAsync;
import hu.rsc.forbiddenwords.client.Forbiddenwords;
import hu.rsc.forbiddenwords.client.table.AdvancedAbstractColumnDefinition;
import hu.rsc.forbiddenwords.client.table.AdvancedPagingScrollTable;
import hu.rsc.forbiddenwords.client.table.FilterChangeListener;
import hu.rsc.forbiddenwords.shared.ApplicationDTO;
import hu.rsc.forbiddenwords.shared.ColumnFilterInfo;
import hu.rsc.forbiddenwords.shared.ColumnFilterList;
import hu.rsc.forbiddenwords.shared.FieldMapping;

import com.google.gwt.gen2.table.client.DefaultRowRenderer;
import com.google.gwt.gen2.table.client.DefaultTableDefinition;
import com.google.gwt.gen2.table.client.FixedWidthGridBulkRenderer;
import com.google.gwt.gen2.table.client.PagingOptions;
import com.google.gwt.gen2.table.client.PagingScrollTable;
import com.google.gwt.gen2.table.client.ScrollTable;
import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
import com.google.gwt.gen2.table.client.TableDefinition;
import com.google.gwt.gen2.table.event.client.RowSelectionEvent;
import com.google.gwt.gen2.table.event.client.RowSelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ApplicationTable extends Composite implements FilterChangeListener, RowSelectionHandler {

    private AdvancedPagingScrollTable<ApplicationDTO> scrollTable;
    private ApplicationTableModel tableModel;
    private final ColumnFilterList columnFilterList = new ColumnFilterList();
    private static final ForbiddenWordsServiceAsync service = Forbiddenwords.getService();
    private final ApplicationPanel parent;

    public ApplicationTable(ApplicationPanel parent) {
	this.parent = parent;
	this.tableModel = new ApplicationTableModel();

	TableDefinition<ApplicationDTO> tableDef = this.createTableDefinition();

	// Create the scroll table
	this.scrollTable = new AdvancedPagingScrollTable<ApplicationDTO>(this.tableModel, tableDef, "Applications", FieldMapping.APP_NAME);
	this.scrollTable.setPageSize(10);
	this.scrollTable.setEmptyTableWidget(new HTML("There are no any application"));

	// Setup the bulk renderer
	FixedWidthGridBulkRenderer<ApplicationDTO> bulkRenderer = new FixedWidthGridBulkRenderer<ApplicationDTO>(this.scrollTable.getDataTable(),
		this.scrollTable);
	this.scrollTable.setBulkRenderer(bulkRenderer);

	// Setup the formatting
	this.scrollTable.setCellPadding(3);
	this.scrollTable.setCellSpacing(0);
	this.scrollTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);
	this.scrollTable.getDataTable().setSelectionPolicy(SelectionPolicy.ONE_ROW);
	this.scrollTable.setHeight("320px");

	this.refreshTable();

	this.scrollTable.getDataTable().addRowSelectionHandler(this);

	VerticalPanel tablePanel = new VerticalPanel();

	HorizontalPanel tablePagingPanel = new HorizontalPanel();
	tablePagingPanel.setWidth("400px");
	tablePagingPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
	tablePanel.add(tablePagingPanel);

	tablePanel.setWidth("400px");
	tablePanel.addStyleName("fullSize");
	tablePanel.add(this.scrollTable);

	tablePagingPanel.add(new PagingOptions(getTable()));

	initWidget(tablePanel);
    }

    public void doFilter() {
	this.scrollTable.reloadPage();
    }

    public PagingScrollTable<ApplicationDTO> getTable() {
	return this.scrollTable;
    }

    @Override
    public void listenForFilterChange(ColumnFilterInfo info) {
	this.columnFilterList.add(info);
	this.refreshTable();
    }

    @Override
    public void onRowSelection(RowSelectionEvent event) {
	ApplicationDTO application = null;
	for (Integer index : this.scrollTable.getDataTable().getSelectedRows()) {
	    application = this.scrollTable.getRowValue(index);
	}
	if (application == null) {
	    return;
	}
	Forbiddenwords.setSelectedApplication(application);
	this.parent.refreshForm(application);

    }

    public void refreshTable() {
	ApplicationTable.service.getApplicationCount(this.columnFilterList, new AsyncCallback<Integer>() {

	    @Override
	    public void onFailure(Throwable t) {
		ApplicationTable.this.tableModel.setRowCount(0);
	    }

	    @Override
	    public void onSuccess(Integer count) {
		ApplicationTable.this.tableModel.setRowCount(count);
		ApplicationTable.this.scrollTable.reloadPage();
	    }
	});
    }

    private TableDefinition<ApplicationDTO> createTableDefinition() {
	// Create the table definition
	DefaultTableDefinition<ApplicationDTO> tableDefinition = new DefaultTableDefinition<ApplicationDTO>();

	// Set the row renderer
	tableDefinition.setRowRenderer(new DefaultRowRenderer<ApplicationDTO>(new String[] { "#FFFFFF", "#EEEEEE" }));

	{
	    AdvancedAbstractColumnDefinition<ApplicationDTO, String> columnDef = new AdvancedAbstractColumnDefinition<ApplicationDTO, String>("name",
		    FieldMapping.APP_NAME, this.tableModel, this, AdvancedAbstractColumnDefinition.MODE_SORT) {

		@Override
		public String getCellValue(ApplicationDTO rowValue) {
		    return rowValue.getName();
		}

		@Override
		public void setCellValue(ApplicationDTO rowValue, String cellValue) {
		    // rowValue.setSzerzo(cellValue);
		}
	    };
	    columnDef.setMinimumColumnWidth(100);
	    columnDef.setPreferredColumnWidth(100);
	    columnDef.setColumnSortable(true);
	    columnDef.setColumnTruncatable(true);
	    columnDef.setHeader(0, columnDef.getHeaderWidget());
	    tableDefinition.addColumnDefinition(columnDef);
	}

	{
	    AdvancedAbstractColumnDefinition<ApplicationDTO, String> columnDef = new AdvancedAbstractColumnDefinition<ApplicationDTO, String>("language",
		    FieldMapping.APP_LANG, this.tableModel, this, AdvancedAbstractColumnDefinition.MODE_SORT) {

		@Override
		public String getCellValue(ApplicationDTO rowValue) {
		    return rowValue.getLanguage();
		}

		@Override
		public void setCellValue(ApplicationDTO rowValue, String cellValue) {
		    // rowValue.setSzerzo(cellValue);
		}
	    };
	    columnDef.setMinimumColumnWidth(100);
	    columnDef.setPreferredColumnWidth(100);
	    columnDef.setColumnSortable(true);
	    columnDef.setColumnTruncatable(true);
	    columnDef.setHeader(0, columnDef.getHeaderWidget());
	    tableDefinition.addColumnDefinition(columnDef);
	}

	{
	    AdvancedAbstractColumnDefinition<ApplicationDTO, String> columnDef = new AdvancedAbstractColumnDefinition<ApplicationDTO, String>("public",
		    FieldMapping.APP_OPENED, this.tableModel, this, AdvancedAbstractColumnDefinition.MODE_SORT) {

		@Override
		public String getCellValue(ApplicationDTO rowValue) {
		    return rowValue.isOpened() ? "yes" : "no";
		}

		@Override
		public void setCellValue(ApplicationDTO rowValue, String cellValue) {
		    // rowValue.setSzerzo(cellValue);
		}
	    };
	    columnDef.setMinimumColumnWidth(100);
	    columnDef.setPreferredColumnWidth(100);
	    columnDef.setColumnSortable(true);
	    columnDef.setColumnTruncatable(true);
	    columnDef.setHeader(0, columnDef.getHeaderWidget());
	    tableDefinition.addColumnDefinition(columnDef);
	}

	{
	    AdvancedAbstractColumnDefinition<ApplicationDTO, String> columnDef = new AdvancedAbstractColumnDefinition<ApplicationDTO, String>("id",
		    FieldMapping.APP_OPENED, this.tableModel, this, AdvancedAbstractColumnDefinition.MODE_ONLY_COLUMNNAME) {

		@Override
		public String getCellValue(ApplicationDTO rowValue) {
		    return rowValue.getId().toString();
		}

		@Override
		public void setCellValue(ApplicationDTO rowValue, String cellValue) {
		    // rowValue.setSzerzo(cellValue);
		}
	    };
	    columnDef.setMinimumColumnWidth(100);
	    columnDef.setPreferredColumnWidth(100);
	    columnDef.setColumnSortable(true);
	    columnDef.setColumnTruncatable(true);
	    columnDef.setHeader(0, columnDef.getHeaderWidget());
	    tableDefinition.addColumnDefinition(columnDef);
	}

	return tableDefinition;
    }

}
